# -*- coding: utf-8 -*-
# article_all.py
# Created by Hardy on 24th, Jan
# Copyright 2017 杭州网川教育科技有限公司. All rights reserved.


from querier.esquerier import ElasticSearchQuerier

READ = 'read_num'
LIKE = 'like_num'
RATIO = 'like_read_ratio'


class WechatArticleAllQuerier(ElasticSearchQuerier):
    def __init__(self, es, index, doc_type, nlp_service=None):
        super(WechatArticleAllQuerier, self).__init__(None, None, None)
        self.es = es
        self.index = index
        self.doc_type = doc_type
        self.nlp_service = nlp_service

    def _build_query(self, args):
        biz_code = args.get('biz_code', None)
        filters = args.get('filters', {})
        filter_clause = [{"term": {"biz_code": biz_code}}]
        order = args.get('order_by')

        if filters:
            filter_clause += add_filter_range_clause(filters, 'publish_timestamp')
            filter_clause += add_filter_range_clause(filters, 'read_num')
            filter_clause += add_filter_range_clause(filters, 'like_num')
            filter_clause += add_filter_range_clause(filters, 'like_read_ratio')

        if biz_code is None:
            raise ValueError('"biz_code" is needed.')
        from_ = args.get('from', 0)
        size_ = args.get('size', 10)

        query = {"query": {
            "bool": {
                "filter": filter_clause
            }
        }, 'from': from_, 'size': size_, 'sort': [{'publish_timestamp': 'desc'}]}
        if order == 'like_read_ratio':
            query['sort'] = [{'like_read_ratio' : 'desc'}, {'publish_timestamp': 'desc'}]
        elif order == 'read_num':
            query['sort'] = [{'read_num': 'desc'}, {'publish_timestamp': 'desc'}]
        elif order == 'like_num':
            query['sort'] = [{'like_num': 'desc'}]
        else:
            query['sort'] = [{'publish_timestamp': 'desc'}, {'publish_timestamp': 'desc'}]
        return query, {}, {}

    def _build_result(self, es_result, param):
        total = es_result['hits']['total']
        articles = []
        for hit in es_result['hits']['hits']:
            articles.append(self.extractResult(hit))
        return {
            'total': total,
            'keywords': [],
            'articles': articles
        }

    def extractResult(self, hit):
        source_ = hit['_source']

        return {
            'biz_code': source_['biz_code'],
            'biz_name': source_['biz_name'],
            'title': source_['title'],
            'url': source_['url'],
            'msg_cdn_url': source_['msg_cdn_url'],
            'read_num': source_['read_num'],
            'like_num': source_['like_num'],
            'publish_timestamp': source_['publish_timestamp'],
            'crawler_timestamp': source_['crawler_timestamp'],
            'keywords': source_['keywords'],
            'category': source_.get('category'),
            'brands': self.nlp_service.get_brands(source_.get('keywords', []))
        }


def add_filter_range_clause(filters, key):
    clause = []
    if key in filters:
        if filters[key]:
            fk = filters[key]
            if not isinstance(fk, list) or len(fk) < 1:
                pass
            else:
                min_fk = fk[0]
                if len(fk) >= 2:
                    max_fk = fk[1]
                else:
                    max_fk = None
                if min_fk is not None and min_fk != 'null':
                    clause.append({'range': {key: {"gte": min_fk}}})
                if max_fk is not None and max_fk != 'null':
                    clause.append({'range': {key: {"lte": max_fk}}})
    return clause


